#include "MacSignatureMessage.hpp"

using namespace BFT::messages;

MacSignatureMessage::MacSignatureMessage(uint16_t _tag, uint32_t _size, int _row_count, int _row_size)
	: VerifiedMessageBase::VerifiedMessageBase(_tag, _size, computeAuthenticationSize(_row_count, _row_size))
{
}

MacSignatureMessage::MacSignatureMessage(boost::shared_ptr<char> _bytes, int _bytes_size)
	: VerifiedMessageBase::VerifiedMessageBase(_bytes, _bytes_size)
{
}

uint32_t MacSignatureMessage::computeAuthenticationSize(int _row_count, int _row_size)
{
	return _row_count * _row_size * MacBytes::size();
}

void MacSignatureMessage::setMacArray(int _index, std::vector<boost::shared_ptr<MacBytes> > _row)
{
	if (internalBytes.size() != 0)
		internalBytes.at(_index) = _row;
		
	int macsize = MacBytes::size();	
	boost::shared_ptr<char> temp_bytes ( (char*)malloc(macsize),free);	
	boost::shared_ptr<char> bytes = getBytes();
	
	int offset = macStartIndex() + _index*_row.size()*macsize;
	for(unsigned int i=0; i<_row.size(); i++)
	{
		temp_bytes = _row.at(i).get()->getBytes();
		memcpy( (void*)(bytes.get()+offset) , (const void *)(temp_bytes.get()) , macsize );
		offset += macsize;
	}		
}

std::vector<boost::shared_ptr<MacBytes> > MacSignatureMessage::getMacArray(int _index, int _row_length)
{
	if (internalBytes.size() > 0)
		return internalBytes.at(_index);
	
	int macsize = MacBytes::size();
	int row_count = getAuthenticationSize() / (_row_length * macsize);
	int offset = macStartIndex();
	boost::shared_ptr<char> temp_bytes ( (char*)malloc(macsize),free);
	boost::shared_ptr<char> bytes = getBytes();
	internalBytes.resize(row_count);
	for(int i=0; i< row_count; i++) //for each row
	{
		internalBytes.at(i).resize(_row_length);
		for(int j=0; j<_row_length; j++) //for each element in the row
		{
			memcpy( (void*)temp_bytes.get(), (const void*)(bytes.get()+offset), macsize);
			internalBytes.at(i).at(j).reset( new MacBytes (temp_bytes));
		}
	}
	
	return internalBytes.at(_index);
}
